package com.itheima.service.impl.ums;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.core.PageInfo;
import com.itheima.mapper.ums.UmsRoleMapper;
import com.itheima.pojo.ums.*;
import com.itheima.pojo.ums.vo.UmsResourceVo;
import com.itheima.pojo.ums.vo.UmsRoleVo;
import com.itheima.service.ums.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;


@DubboService
public class UmsRoleServiceImpl extends ServiceImpl<UmsRoleMapper, UmsRole> implements UmsRoleService {
    @DubboReference
    private UmsRoleMenuRelationService umsRoleMenuRelationService;
    @DubboReference
    private UmsMenuService umsMenuService;
    @DubboReference
    private UmsResourceService umsResourceService;
    @DubboReference
    private UmsRoleResourceRelationService umsRoleResourceRelationService;

    /**
     * 添加角色
     *
     * @param umsRole
     * @return
     */
    @Override
    public void create(UmsRole umsRole) {
        umsRole.setCreateTime(LocalDateTime.now());
        this.save(umsRole);
    }

    /**
     * 批量删除角色
     *
     * @param ids
     * @return
     */
    @Override
    public void delete(List<Long> ids) {
        LambdaQueryWrapper<UmsRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(UmsRole::getId, ids);
        this.remove(queryWrapper);
    }

    /**
     * 根据角色名称分页获取角色列表
     *
     * @param keyword
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public PageInfo roleList(String keyword, Integer pageSize, Integer pageNum) {
        Page<UmsRole> umsRolePage = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<UmsRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(keyword != null, UmsRole::getName, keyword)
                .orderByAsc(UmsRole::getSort);
        Page<UmsRole> page = this.page(umsRolePage, queryWrapper);
        //封装分页数据
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(pageNum);
        pageInfo.setList(page.getRecords());
        pageInfo.setTotal((int) page.getTotal());
        pageInfo.setTotalPage((int) page.getCurrent());
        return pageInfo;
    }

    /**
     * 获取所有角色
     *
     * @return
     */
    @Override
    public List<UmsRole> listAll() {
        LambdaQueryWrapper<UmsRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(UmsRole::getSort);
        List<UmsRole> list = this.list(queryWrapper);
        return list;
    }

    /**
     * 获取角色相关菜单
     *
     * @param roleId
     * @return
     */
    @Override
    public List<UmsMenu> listMenu(Integer roleId) {
        UmsRole umsRole = this.getById(roleId);
        LambdaQueryWrapper<UmsRoleMenuRelation> queryWrapper = new LambdaQueryWrapper<>();
        //获取角色相关菜单
        queryWrapper.eq(UmsRoleMenuRelation::getRoleId, umsRole.getId());
        //获取所有相关
        List<UmsRoleMenuRelation> roleMenuRelationList = umsRoleMenuRelationService.list(queryWrapper);
        List<UmsMenu> umsMenuList = roleMenuRelationList.stream().map(item -> {
            UmsMenu umsMenu = umsMenuService.getById(item.getMenuId());
            return umsMenu;
        }).collect(Collectors.toList());
        return umsMenuList;
    }

    /**
     * 获取角色相关资源
     *
     * @param roleId
     * @return
     */
    @Override
    public List<UmsResource> listResource(Integer roleId) {
        UmsRole umsRole = this.getById(roleId);
        //获取角色相关资源
        LambdaQueryWrapper<UmsRoleResourceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UmsRoleResourceRelation::getRoleId, umsRole.getId());
        List<UmsRoleResourceRelation> resourceRelationList = umsRoleResourceRelationService.list(queryWrapper);
        List<UmsResource> umsResourceList = resourceRelationList.stream().map(item -> {
            UmsResource umsResource = umsResourceService.getById(item.getResourceId());
            return umsResource;
        }).collect(Collectors.toList());
        return umsResourceList;
    }


    /**
     * 修改角色
     *
     * @param umsRole
     * @return
     */
    @Override
    public void updateUmsRole(UmsRole umsRole) {
        this.updateById(umsRole);
    }

    /**
     * 修改角色状态
     *
     * @param id
     * @return
     */
    @Override
    public void updateStatus(Integer id, Long status) {
        UmsRole umsRole = this.getById(id);
        umsRole.setStatus(status);
        this.updateById(umsRole);
    }

    /**
     * 给角色分配菜单
     *
     * @param umsRoleVo
     * @return
     */
    @Override
    public void allocMenu(UmsRoleVo umsRoleVo) {
        List<Long> menuIds = umsRoleVo.getMenuIds();
        List<UmsRoleMenuRelation> menuRelationList = menuIds.stream().map(menuId -> {
                    UmsRoleMenuRelation umsRoleMenuRelation = new UmsRoleMenuRelation();
                    umsRoleMenuRelation.setRoleId(umsRoleVo.getRoleId());
                    umsRoleMenuRelation.setMenuId(menuId);
                    return umsRoleMenuRelation;
                }).collect(Collectors.toList());
        LambdaQueryWrapper<UmsRoleMenuRelation> relationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        relationLambdaQueryWrapper.eq(UmsRoleMenuRelation::getRoleId,umsRoleVo.getRoleId());
        umsRoleMenuRelationService.remove(relationLambdaQueryWrapper);
        umsRoleMenuRelationService.saveBatch(menuRelationList);
    }

    /**
     * 给角色分配资源
     * @param umsResourceVo
     * @return
     */
    @Override
    public void allocResource(UmsResourceVo umsResourceVo) {
        List<Long> resourceIds = umsResourceVo.getResourceIds();
        List<UmsRoleResourceRelation> resourceRelationList = resourceIds.stream().map(resourceId -> {
            UmsRoleResourceRelation umsRoleResourceRelation = new UmsRoleResourceRelation();
            umsRoleResourceRelation.setRoleId(umsResourceVo.getRoleId());
            umsRoleResourceRelation.setResourceId(resourceId);
            return umsRoleResourceRelation;
        }).collect(Collectors.toList());
        LambdaQueryWrapper<UmsRoleResourceRelation> umsRoleResourceRelationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        umsRoleResourceRelationLambdaQueryWrapper.eq(UmsRoleResourceRelation::getRoleId,umsResourceVo.getRoleId());
        umsRoleResourceRelationService.remove(umsRoleResourceRelationLambdaQueryWrapper);
        umsRoleResourceRelationService.saveBatch(resourceRelationList);
    }
}
